<?php

namespace App\Logic\Purchase;

use App\Core\BaseCore;
use App\Core\BaseModel;
use App\Core\Exception\DefaultException;
use App\Core\Output;
use App\Logic\Purchase\Form\EditPurchaseForm;
use App\Logic\Purchase\Form\PurchaseListForm;
use App\Logic\Purchase\Form\SubmitPurchaseForm;
use App\Model\Order\OrderTaskStatisticsModel;
use App\Model\Purchase\PurchaseModel;
use App\Util\ArrayHelper;
use EasySwoole\Component\Singleton;
use EasySwoole\Http\Request;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Exception\Exception;
use EasySwoole\RedisPool\RedisPool;
use Throwable;

class PurchaseService extends BaseCore
{

    use Singleton;

    /**
     * 字典数据
     * @param Request $request
     * @return Output
     * @throws Exception
     * @throws Throwable
     */
    public function getDict(Request $request) : Output
    {

        return $this->success([
            'order_state'   => ArrayHelper::keyArrayToList(PurchaseModel::getOrderStateDict()),
        ]);
    }

    /**
     * 创建订单
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function create($data) : Output
    {
        $purchaseForm = new SubmitPurchaseForm($data);
        $result = $purchaseForm->submit();
        return $result;
    }

    /**
     * 编辑订单
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function edit($data) : Output
    {
        $purchaseForm = new EditPurchaseForm($data);
        $result = $purchaseForm->edit();
        return $result;
    }

    /**
     * 订单列表
     * @param Request $request
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\Redis\Exception\RedisException
     */
    public function getLists(Request $request){
        $params    = $request->getQueryParams();
        $cache     = RedisPool::defer();
        $cache_key = "purchaseCache:lists:" . json_encode($params);
        if ($cache_data = $cache->get($cache_key)) { //缓存存在
            $data = json_decode($cache_data, true);
        } else {
            $form = new PurchaseListForm($params, $request);
            $data = $form->lists();
            $cache->set($cache_key, json_encode($data), BaseModel::CACHE_EXPIRE);
        }

        return $this->success($data);
    }

    private $op = '<';//用于测试的时候调试
    /**
     * 自动设置订单状态为SHIPPED:已发货
     */
    public function orderStateShipped()
    {
        $result = PurchaseModel::create()->where('order_state', PurchaseModel::UNSHIPPING)->where('shipped_time', date('Y-m-d H:i:s'), $this->op)->limit(PurchaseModel::ORDERLIMIT)->field('id')->all();
        if ($order_ids = array_column($result->toRawArray(), 'id')) {
            $res = PurchaseModel::create()->updateData(['order_state' => PurchaseModel::SHIPPED], ['id' => [$order_ids, 'IN']]);
            return $res->lastQueryResult()->getAffectedRows();
        }
        return count($result);
    }

    /**
     * 自动设置订单状态为RECEIPT:已收货
     */
    public function orderStateReceipt()
    {
        $result = PurchaseModel::create()->where('order_state', PurchaseModel::SHIPPED)->where('receipt_time', date('Y-m-d H:i:s'), $this->op)->field('id')->limit(PurchaseModel::ORDERLIMIT)->all();
        if ($order_ids = array_column($result->toRawArray(), 'id')) {
            $res = PurchaseModel::create()->updateData(['order_state' => PurchaseModel::RECEIPT], ['id' => [$order_ids, 'IN']]);
            return $res->lastQueryResult()->getAffectedRows();
        }
        return count($result);
    }

    /**统计订单数量和金额*/
    public function countOrder()
    {
        $sta = [
            'count_unshipping_purchase' => 0,
            'unshipping_purchase_amount' => 0,
            'count_shipped_purchase' => 0,
            'shipped_purchase_amount' => 0,
            'count_receipt_purchase' => 0,
            'receipt_purchase_amount' => 0,
        ];
        $query = PurchaseModel::makeQueryModel()->field('order_state, COUNT(1) `c`, SUM(order_amount) `s`')->group('order_state')->all();
        foreach ($query as $item){
            $sta['count_'. strtolower($item['order_state']) .'_purchase'] = $item['c'];
            $sta[strtolower($item['order_state']) .'_purchase_amount'] = $item['s'];
        }
//        $sql = "SELECT order_state, COUNT(1) `c`, SUM(order_amount) `s` FROM `" . PurchaseModel::create()->getTableName() . "` WHERE is_delete=0 GROUP BY order_state";
//
//        $queryBuild = new QueryBuilder();
//        $queryBuild->raw($sql);
//        $result = DbManager::getInstance()->query($queryBuild, true);
//
//        if ($staRes = $result->getResult()) {
//
//            foreach ($staRes as $item) {
//                $sta['count_'. strtolower($item['order_state']) .'_purchase'] = $item['c'];
//                $sta[strtolower($item['order_state']) .'_purchase_amount'] = $item['s'];
//            }
//
//        }
        $sta['count_purchase'] = $sta['count_unshipping_purchase'] + $sta['count_shipped_purchase'] + $sta['count_receipt_purchase'];
        $sta['purchase_amount'] = bcadd(bcadd($sta['unshipping_purchase_amount'], $sta['shipped_purchase_amount'], 2), $sta['receipt_purchase_amount'], 2);
        return $sta;
    }
}
